
import socketserver,json,os,shutil,time,subprocess

class MyTCPHandler(socketserver.BaseRequestHandler):

    current_p=os.getcwd()
    def put(self,*args):
        '''接收客户端文件'''
        cmd_dic=args[0]
        filename=cmd_dic["filename"]
        filesize=cmd_dic["size"]
        if os.path.isfile(filename):
            os.remove(filename)
            f=open(filename,"wb")
        else:
            print("file not exits!",filename)
            f=open(filename,"wb")
        self.request.send(b"200 ok")
        received_size=0
        while received_size<filesize:
            data=self.request.recv(1024)
            received_size+=len(data)
            f.write(data)
        else:
            print("file [%s] has uploaded ..."%filename)
            f.close()

    def get(self,*args):
        '''发送服务端文件'''
        cmd_dic=args[0]
        filename=cmd_dic["filename"]
        action=cmd_dic["action"]
        os.chdir(MyTCPHandler.current_p)
        if os.path.isfile(filename):
            filesize=os.stat(filename).st_size   ##获取文件大小
            print("file:%s is exist"%filename)
            server_dic={
                "action":action,
                "filename":filename,
                "filesize":filesize,
                # "action":True,
            }
            self.request.send(json.dumps(server_dic).encode("utf-8"))
            client_response=self.request.recv(1024)   ##接收客户端的响应
            print(client_response)
            print("file:[%s] start send"%filename)
            f=open(filename,"rb")
            for line in f:
                self.request.send(line)
            f.close()
            print("file:[%s] has send done"%filename)
        else:
            print("file:%s is not exist"%filename)

    def sh(self,*args):
        cmd_dic=args[0]
        action=cmd_dic["action"]
        command=cmd_dic["command"]
        print("command:",command)
        if os.name == "posix":
            try:
                s=subprocess.run(command,stdout=subprocess.PIPE,stderr=subprocess.PIPE,universal_newlines=True)
                msg_dic=s.__dict__
                print("server_dic",msg_dic["stdout"])
                shell_dic={
                    "action":action,
                    "command":command,
                    "msg_server":msg_dic,
                }  
            
                self.request.send(json.dumps(shell_dic).encode("utf-8"))
            except FileNotFoundError :
                print("no data response")
                msg_dic={
                        "stdout":"cmd can't excute success,please enter anothere command. current path:%s"%MyTCPHandler.current_p,
                        }
                shell_dic={
                    "action":action,
                    "command":command,
                    "msg_server":msg_dic,
                        }
                self.request.send(json.dumps(shell_dic).encode("utf-8"))
        elif os.name == "nt":
            for i in command:
                cmd_p=i+''
            print(cmd_p)
            s=os.popen(cmd_p).read()
            shell_dic={
                "action":action,
                "command":command,
                "msg_server":s,
            }
            self.request.send(json.dumps(shell_dic).encode("utf-8"))
        else:
            print("os platform is not surport! can't excute command!")
            shell_dic={
                "action":action,
                "command":command,
                "msg_server":"os platform {%s} is not surport! can't excute command!"%os.name,
            }
            self.request.send(json.dumps(shell_dic).encode("utf-8"))

    def cd(self,*args):   
        cmd_dic=args[0]
        action=cmd_dic["action"]
        file=cmd_dic["file"]
        if file=="..":
            current_path=os.path.split(MyTCPHandler.current_p)[0]
            print(current_path)
            MyTCPHandler.current_p=current_path
            current_file=os.listdir(current_path)
            msg_dic={
                "action":action,
                "current_path":current_path,
                "current_file":current_file,
                "msg":"ok",
            }
            self.request.send(json.dumps(msg_dic).encode("utf-8"))
        else:
            current_path=os.path.join(MyTCPHandler.current_p,file)
            print(current_path)
            if os.path.exists(current_path):   
                MyTCPHandler.current_p=current_path             
                current_file=os.listdir(current_path)
                msg_dic={
                    "action":action,
                    "current_path":current_path,
                    "current_file":current_file,
                    "msg":"ok",
                }
                self.request.send(json.dumps(msg_dic).encode("utf-8"))
            else:
                print("%s is not exists"%os.path.join(current_path,file))
                msg_dic={
                        "action":action,
                        "current_path":current_path,
                        "current_file":'',
                        "msg":"%s is not exists"%current_path,
                    }
                self.request.send(json.dumps(msg_dic).encode("utf-8"))

    def rm(self,*args):
        cmd_dic=args[0]
        action=cmd_dic["action"]
        filename=cmd_dic["filename"]
        # file_list=os.listdir(".")
        os.chdir(MyTCPHandler.current_p)
        if os.path.isfile(filename): 
            # os.chdir(MyTCPHandler.current_p)
            os.remove(filename)
            msg_dic={
                "action":action,
                "msg":"%s has delete."%filename,
                "err":'',
            } 
            self.request.send(json.dumps(msg_dic).encode("utf-8"))
        elif os.path.isdir(filename):
            # os.chdir(MyTCPHandler.current_p)
            shutil.rmtree(filename)
            msg_dic={
                "action":action,
                "msg":"%s has delete."%filename,
                "err":'',
            } 
            self.request.send(json.dumps(msg_dic).encode("utf-8"))
        else:
            msg_dic={
                "msg":'',
                "err":"%s is not exist."%filename,
            } 
            self.request.send(json.dumps(msg_dic).encode("utf-8"))

    def rename(self,*args):
        current=MyTCPHandler.current_p
        cmd_dic=args[0]
        action=cmd_dic["action"]
        oldname=cmd_dic["oldname"]
        newname=cmd_dic["newname"]
        if os.path.exists(os.path.join(current,oldname)):
            os.chdir(current)
            os.rename(oldname,newname)
            msg_dic={
                "action":action,
                "msg":"%s has been renamed %s"%(oldname,newname),
                "err":"",
            }
            self.request.send(json.dumps(msg_dic).encode("utf-8"))
        else:
            print("%s file is not exists"%oldname)
            msg_dic={
                "action":action,
                "msg":"",
                "err":"%s file is not exists"%oldname,
            }
            self.request.send(json.dumps(msg_dic).encode("utf-8"))

    def unpack(self,*args):
        cmd_dic=args[0]
        action=cmd_dic["action"]
        filename=cmd_dic["filename"]
        
        # if os.path.exists(os.path.join(MyTCPHandler.current_p,filename)) and shutil.endswith(filename)==".zip":
        if os.path.exists(os.path.join(MyTCPHandler.current_p,filename)):
            os.chdir(MyTCPHandler.current_p)
            shutil.unpack_archive(filename,'./')              ##解压缩zip文件
            msg_dic={
                "action":action,
                "msg":"%s filename has unpack"%filename,
                "err":''
            }
            self.request.send(json.dumps(msg_dic).encode("utf-8"))
        else:
            print("%s is no exist or file formart is wrong"%filename)
            msg_dic={
                "action":action,
                "msg":'',
                "err":"%s is no exist or file formart is wrong"%filename
            }
            self.request.send(json.dumps(msg_dic).encode("utf-8"))

    def tz(self,*args):
        cmd_dic=args[0]
        action=cmd_dic["action"]
        filename=cmd_dic["filename"]
        tz_filename=cmd_dic["tz_filename"]
        format=cmd_dic["format"]
        try:
            if os.path.exists(os.path.join(MyTCPHandler.current_p,filename)):
                os.chdir(MyTCPHandler.current_p)
                shutil.make_archive(tz_filename,format,'./'+filename)
                time.sleep(2)
                msg_dic={
                    "action":action,
                    "msg":"%s filename has make_archived %s"%(filename,tz_filename),
                    "format":format,
                    "filesize":os.stat(tz_filename+'.'+format).st_size/(1024*1024),
                    "err":''
                }
                self.request.send(json.dumps(msg_dic).encode("utf-8"))
            else:
                print("%s is no exists "%filename)
                msg_dic={
                    "action":action,
                    "msg":'',
                    "format":format,
                    "filesize":'',
                    "err":"%s is no exists "%filename
                }
                self.request.send(json.dumps(msg_dic).encode("utf-8"))
        except:
            print("something wrong")

    def ls(self,*args):
        cmd_dic=args[0]
        if cmd_dic["action"] == "ls":

            file_list=os.listdir(MyTCPHandler.current_p)
            check_dic={
                "ls":file_list,
            }
            self.request.send(json.dumps(check_dic).encode("utf-8"))
        else:
            pass

    def pwd(self,*args):
        cmd_dic=args[0]
        # print(cmd_dic)
        work_path=MyTCPHandler.current_p
        # print(work_path)
        check_dic={
            "pwd":work_path,
        }
        self.request.send(json.dumps(check_dic).encode("utf-8"))

    def mkdir(self,*args):
        cmd_dic=args[0]
        action=cmd_dic["action"]
        filename=cmd_dic["filename"]
        # os.chdir(MyTCPHandler.current_p)
        if os.path.exists(os.path.join(MyTCPHandler.current_p,filename)):
            msg_dic={
                "action":action,
                "msg":"%s has been exists"%filename,
                "filename":filename,
            }
            self.request.send(json.dumps(msg_dic).encode("utf-8"))
        else:
            os.chdir(MyTCPHandler.current_p)
            os.mkdir(filename)
            msg_dic={
                "action":action,
                "msg":"%s has created"%filename,
                "filename":filename,
            }
            self.request.send(json.dumps(msg_dic).encode("utf-8"))
      
    def handle(self):
        while True:
            try:
                self.data=self.request.recv(1024).strip()
                print("{} write:".format(self.client_address[0]))
                print(self.data)
                cmd_dic=json.loads(self.data.decode())
                action=cmd_dic["action"]
                if hasattr(self,action):
                    func=getattr(self,action)
                    func(cmd_dic)


            except ConnectionResetError as e:
                print("err",e)
                break

if __name__=="__main__":
    Host,Port ="0.0.0.0",9998
    # server=socketserver.TCPServer((Host,Port),MyTCPHandler)

    server=socketserver.ThreadingTCPServer((Host,Port),MyTCPHandler)
    server.serve_forever()
